<template>
    <el-container class="layout-console">
        <input type="file" accept="image/*" hidden ref="select-avatar-input" @change="handleSelectedAvatar($event)" />
        <el-aside width="200px" class="aside">
            <div class="logo">管理后台</div>
            <div class="navs">
                <el-menu :default-active="defaultActive" class="menu-aside" mode="vertical" background-color="#444444" text-color="#ffffff" active-text-color="#409EFF">
                    <template v-for="(item, i) in menuTree">
                        <el-menu-item :index="item.path" :key="i" v-if="item.children.length == 0">
                            <div class="menu-item" @click="handleSelect(item)">
                                <i :class="item.icon" v-if="item.icon"></i>
                                <span class="name">{{ item.name }}</span>
                            </div>
                        </el-menu-item>
                        <el-submenu :index="item.path || i + ''" :key="i" v-else>
                            <template slot="title">
                                <div class="menu-item">
                                    <i :class="item.icon" v-if="item.icon"></i>
                                    <span class="name">{{ item.name }}</span>
                                </div>
                            </template>
                            <template v-for="(child, c) in item.children">
                                <el-menu-item :index="child.path" :key="c">
                                    <div class="menu-item" @click="handleSelect(child)">
                                        <i :class="child.icon" v-if="child.icon"></i>
                                        <span class="name">{{ child.name }}</span>
                                    </div>
                                </el-menu-item>
                            </template>
                        </el-submenu>
                    </template>
                </el-menu>
            </div>
        </el-aside>
        <el-container class="container">
            <el-header class="header">
                <el-breadcrumb separator="/">
                    <el-breadcrumb-item :to="{ name: 'console' }">
                        <i class="el-icon-s-home"></i>
                        <span style="margin-left: 5px">首页</span>
                    </el-breadcrumb-item>
                    <el-breadcrumb-item>{{ $route.meta.title }}</el-breadcrumb-item>
                </el-breadcrumb>
                <el-dropdown trigger="click" @command="selectedItem">
                    <span class="user-dropdown">
                        <el-avatar icon="el-icon-user-solid" :src="userInfo.avatar" :size="32"></el-avatar>
                        <span class="nickname">{{ userInfo.nickname || "未设置昵称" }}</span>
                        <i class="el-icon-arrow-down el-icon--right"></i>
                    </span>
                    <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item command="changeAvatar">更换头像</el-dropdown-item>
                        <el-dropdown-item>修改信息</el-dropdown-item>
                        <el-dropdown-item command="logout">退出账号</el-dropdown-item>
                    </el-dropdown-menu>
                </el-dropdown>
            </el-header>
            <el-main class="main">
                <router-view></router-view>
            </el-main>
            <el-footer class="footer">
                <p>本后台由<a href="https://www.kancloud.cn/manual/thinkphp6_0/1037479" target="_blank">ThinkPHP6.0</a>|<a href="https://element.eleme.cn/#/zh-CN/component/installation" target="_blank">ElementUI</a>强力驱动</p>
            </el-footer>
        </el-container>
        <el-dialog title="更换头像" class="dialog-cropper-avatar" :visible.sync="showDialogChangeAvatar" width="520px" :close-on-click-modal="false">
            <div class="cropper-container">
                <div class="cropper-area">
                    <vue-cropper ref="cropper" :img="option.img" :outputSize="option.size" :outputType="option.outputType" :autoCrop="option.autoCrop" :autoCropWidth="option.autoCropWidth" :autoCropHeight="option.autoCropHeight" :centerBox="option.centerBox" :fixedNumber="option.fixedNumber" :fixed="option.fixed" @realTime="handlePreviewCropper"></vue-cropper>
                </div>
                <div class="preview-area">
                    <div class="preview">
                        <div class="preview-box" style="width: 100px; height: 100px">
                            <div :style="previewStyle1">
                                <div :style="previews.div">
                                    <img :src="previews.url" :style="previews.img" />
                                </div>
                            </div>
                        </div>
                        <div class="preview-size">100*100</div>
                    </div>
                    <div class="preview">
                        <div class="preview-box" style="width: 50px; height: 50px">
                            <div :style="previewStyle2">
                                <div :style="previews.div">
                                    <img :src="previews.url" :style="previews.img" />
                                </div>
                            </div>
                        </div>
                        <div class="preview-size">50*50</div>
                    </div>
                </div>
            </div>
            <template slot="footer">
                <el-button type="text" @click="changeAvatar" icon="el-icon-refresh-right">重新选择图片</el-button>
                <el-button type="primary" @click="saveAvatar">保存</el-button>
            </template>
        </el-dialog>
    </el-container>
</template>

<script>
const routerMode = process.env.VUE_APP_ROUTER_MODE;

import { VueCropper } from "vue-cropper";
export default {
    components: { VueCropper },
    data() {
        return {
            showDialogChangeAvatar: false,
            option: {
                img: "",
                size: 1,
                outputType: "jpeg",
                autoCrop: true,
                autoCropWidth: 200,
                autoCropHeight: 200,
                centerBox: true,
                fixed: true,
                fixedNumber: [1, 1],
            },
            previews: {},
            previewStyle1: {},
            previewStyle2: {},
            defaultActive: "",
        };
    },
    created() {
        this.getUserInfo();

        if (routerMode === "hash") this.defaultActive = window.location.hash.replace(/^#/, "");
        if (routerMode === "history") this.defaultActive = window.location.pathname;
    },
    computed: {
        userInfo() {
            return this.$store.state.userInfo || {};
        },
        roleInfo(){
            return this.userInfo.role_info || {};
        },
        menuTree() {
            return this.roleInfo.menu_tree || [];
        },
    },
    methods: {
        saveAvatar() {
            this.$refs.cropper.getCropBlob((data) => {
                this.showDialogChangeAvatar = false;
            });
        },
        handlePreviewCropper(data) {
            const previews = data;

            this.previewStyle1 = {
                width: previews.w + "px",
                height: previews.h + "px",
                overflow: "hidden",
                margin: "0",
                zoom: 100 / previews.h,
            };

            this.previewStyle2 = {
                width: previews.w + "px",
                height: previews.h + "px",
                overflow: "hidden",
                margin: "0",
                zoom: 50 / previews.h,
            };

            this.previews = previews;
        },
        handleSelectedAvatar(e) {
            const elem = e.srcElement || e.target;
            const files = Array.from(elem.files);
            const { showDialogChangeAvatar } = this;

            if (files.length > 0) {
                const file = files[0];

                this.option.img = URL.createObjectURL(file);
                URL.revokeObjectURL(file);
                elem.value = "";

                this.$nextTick(() => {
                    if (!showDialogChangeAvatar) this.showDialogChangeAvatar = true;
                });
            }
        },
        selectedItem(cmd) {
            switch (cmd) {
                case "logout":
                    this.logout();
                    break;
                case "changeAvatar":
                    this.changeAvatar();
                    break;
            }
        },
        changeAvatar() {
            this.$refs["select-avatar-input"].click();
        },
        logout() {
            this.$confirm("确认要退出当前账号吗? 退出后你需要重新登陆!", "退出确认", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(() => {
                    this.returnLoginPage();
                })
                .catch(() => {});
        },
        returnLoginPage() {
            window.localStorage.clear();
            window.sessionStorage.clear();
            this.$router.push({ name: "login" });
        },
        handleSelect(data) {
            const { path, target } = data;

            if (path) {
                switch (target) {
                    case "_blank":
                        window.open(path);
                        break;
                    default:
                        this.$router.push({ path });
                        break;
                }
            }
        },
        getUserInfo() {
            this.$get("/user/getUserInfo").then((res) => {
                const { code, data } = res;

                if (code == 200) {
                    this.$store.commit("updateUserInfo", data);
                } else {
                    this.returnLoginPage();
                }
            });
        },
    },
};
</script>

<style lang="scss" scoped>
.layout-console {
    height: 100vh;
    width: 100vw;
    overflow: hidden;
    background-color: #f6f6f6;
    .dialog-cropper-avatar {
        .cropper-container {
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            .cropper-area {
                flex-shrink: 0;
                height: 320px;
                width: 320px;
            }
            .preview-area {
                flex: 1;
                display: flex;
                flex-direction: column;
                align-items: center;
                .preview {
                    display: flex;
                    flex-direction: column;
                    justify-content: center;
                    align-items: center;
                    .preview-box {
                        background-color: #888;
                        border-radius: 50%;
                        overflow: hidden;
                    }
                    .preview-size {
                        font-size: 12px;
                        margin: 10px 0px;
                        color: gray;
                    }
                }
            }
        }
    }
    .aside {
        background-color: #444;
        .logo {
            background-color: #333;
            color: #fff;
            height: 60px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 24px;
            box-shadow: 0px 1px 5px rgba($color: #000000, $alpha: 0.1);
        }
        .menu-aside {
            border-width: 0px;

            .menu-item {
                display: flex;
                align-items: center;
                > i {
                    font-size: 16px;
                    width: 1.5em;
                    text-align: left;
                }
            }
        }
    }
    .container {
        .header,
        .footer {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .header {
            background-color: #fff;
            box-shadow: 0px 1px 5px rgba($color: #000000, $alpha: 0.1);

            .user-dropdown {
                cursor: pointer;
                display: flex;
                align-items: center;
                .nickname {
                    padding: 0px 5px;
                }
            }
        }
        .footer {
            font-size: 13px;
            color: gray;

            a {
                color: gray;
                display: inline-block;
                margin: 0px 5px;
                text-decoration: none;
            }
        }
    }
}
</style>
